import { Inject, Provide, App, Init } from '@midwayjs/core';
import { BaseService } from '@cool-midway/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm';
import { OrderOrderEntity } from '../../order/entity/order';
import { PluginService } from '../../plugin/service/info';

import { UserInfoEntity } from '../../user/entity/info';
import { NursingPersonEntity } from '../../nursing/entity/person'
import { AddressInfoEntity } from '../../address/entity/info'
import { NurseInfoEntity } from '../../nurse/entity/info'
import { DictInfoEntity } from '../../dict/entity/info'
import { PayConfigEntity } from '../../pay/entity/config'

import * as fs from 'fs';
import * as path from 'path';
import { IMidwayKoaApplication } from '@midwayjs/koa';
let WxPay = require('wechatpay-node-v3');

// select: ['a.*', 'b.name as beNurseName','c.province','c.city','c.district','c.detailAddress','d.nickName'],
//     join: [
//       {
//         entity: NursingPersonEntity,
//         alias: 'b',
//         condition: 'a.beNurseId = b.id',
//         type: 'leftJoin',
//       },
//       {
//         entity: AddressInfoEntity,
//         alias: 'c',
//         condition: 'a.beNurseAddressId = c.id',
//         type: 'leftJoin',
//       },
//       {
//         entity: UserInfoEntity,
//         alias: 'd',
//         condition: 'a.openid = d.unionid',
//         type: 'leftJoin',
//       }
//     ],


/**
 * 订单信息
 */
@Provide()
export class AppOrderPayService extends BaseService {
    @InjectEntityModel(OrderOrderEntity)
    orderOrderEntity: Repository<OrderOrderEntity>;

    @InjectEntityModel(NursingPersonEntity)
    nursingPersonEntity: Repository<NursingPersonEntity>;

    @Inject()
    pluginService: PluginService;

    @InjectEntityModel(DictInfoEntity)
    dictInfoEntity: Repository<DictInfoEntity>;

    @InjectEntityModel(PayConfigEntity)
    payConfigEntity: Repository<PayConfigEntity>;

    @Inject()
    ctx;

    @App()
    app: IMidwayKoaApplication;

    // @Init()
    // async init() {
    //     await super.init();
    //     this.setEntity(this.nursingPersonEntity);
    // }

    // 微信支付订单
    async createOrder(BodyData) {
        let appid = ''
        let mchid = ""
        let keyFileName = ""
        let keyFoldersName = ""
        let certFileName = ""
        let certFoldersName = ""
        let notify_url = ""
        let { openid } = BodyData
        let createById = this.ctx.user.id
        // 生成订单号
        let date = new Date()
        let year = date.getFullYear() + ''
        let _mount = date.getMonth() + 1
        let _day = date.getDate()
        let mount = _mount < 10 ? ('0' + _mount) : _mount
        let day = _day < 10 ? ('0' + _day) : _day
        let orderTimer = year + mount + day
        function generateShortUUID() {
            return Math.floor(Math.random() * 100000000).toString().padStart(8, '0');
        }
        let createOrderNum = orderTimer + generateShortUUID()
        // orderId: createOrderNum, // 订单号
        // goodsName: "", // 商品名称
        // goodsType: "", // 商品类型
        // serviceProject: "", // 服务项目
        // serviceDay: "", // 服务时长天
        // startTime: "", // 服务开始时间
        // price: "", // 单价
        // totalPrice: "", // 总价
        // beNurseId: "", // 被护理人Id
        // beNurseAddressId:1, // 被护理人地址
        let {
            goodsName,
            goodsType,
            serviceProject,
            serviceDay,
            startTime,
            totalPrice,
            beNurseId,
            beNurseAddressId,
            serveId,
            remark
        } = BodyData
        let orderPayItem = await this.payConfigEntity.findOneBy({ baseStatus: 1 })
        let { mchId, appId, apiclient_key, apiclient_cert, notifyUrl } = orderPayItem
        console.log(orderPayItem, 'orderPayItem')
        if (!mchId || !appId || !apiclient_key || !apiclient_cert || !notifyUrl) {
            throw new Error("商户信息不全，请联系管理员")
        } else {
            let apiclientKey = apiclient_key.split('/')
            let apiclientCert = apiclient_cert.split('/')
            appid = appId
            mchid = mchId
            keyFileName = apiclientKey[0]
            keyFoldersName = apiclientKey[1]
            certFileName = apiclientCert[0]
            certFoldersName = apiclientCert[1]
            notify_url = notifyUrl
        }
        let serveceObj: any = await this.dictInfoEntity.findOneBy({ id: serveId })
        console.log(serveceObj, 'serveceObj')
        let paramsOrder: any = {
            orderNum: createOrderNum,
            goodsName,
            goodsType,
            serviceProject,
            serviceDay,
            startTime,
            price: Number(serveceObj.value),
            totalPrice: Number(serveceObj.value) * Number(serviceDay),
            beNurseId,
            beNurseAddressId,
            openid,
            serveId,
            createById,
            remark
        }
        console.log(BodyData, 'BodyData', paramsOrder)
        let resOrder = await this.orderOrderEntity.save(paramsOrder)
        const filePathkey = path.join(
            this.app.getBaseDir(),
            '..',
            'src',
            'modules',
            'order',
            'service',
            keyFileName,
            keyFoldersName
        );
        const filePathCert = path.join(
            this.app.getBaseDir(),
            '..',
            'src',
            'modules',
            'order',
            'service',
            certFileName,
            certFoldersName
        );
        const pay = new WxPay({
            appid, // '直连商户申请的公众号或移动应用appid'
            mchid,
            publicKey: fs.readFileSync(filePathCert), // 公钥
            privateKey: fs.readFileSync(filePathkey), // 秘钥
        });

        try {
            let params = {
                appid,
                mchid,
                "out_trade_no": createOrderNum,
                "description": "平面设计VIP套餐",
                "notify_url": notify_url,
                "amount": {
                    "total": Math.floor(Number(paramsOrder.totalPrice) * 100),
                    "currency": "CNY"
                },
                "payer": {
                    openid
                }
            }
            const result1 = await pay.transactions_jsapi(params);
            result1.data.out_trade_no = createOrderNum
            result1.data.id = resOrder.id
            console.log(result1, 'result1')
            return result1
        } catch (error) {
            console.log(error, 'error')
            return error
        }
    }

    // 获取订单分页
    async getOrderPage(BodyData) {
        console.log(this.ctx.user.id, 'this.ctx.user.id', BodyData)
        // find.leftJoinAndSelect(NursingPersonEntity, 'nursing', 'nursing.id = order.beNurseId')
        // // .leftJoinAndSelect(UserInfoEntity, 'user', 'order.openid = user.unionid')
        // .getRawMany();
        // find.leftJoin
        let id = this.ctx.user.id
        const find = this.orderOrderEntity.createQueryBuilder('a')
            // .leftJoin(NursingPersonEntity, 'b', 'a.beNurseId = b.id')
            // .orderBy('a.createById', 'DESC')
            // .where('a.createById = :id', { id })
            // .select([
            //     'a.id'
            // ])
            .select([
                'a',
            ])
            .leftJoinAndMapOne(
                'a.beNurseInfo',
                NursingPersonEntity,
                'b',
                'b.id = a.beNurseId'
            )
            .leftJoinAndMapOne(
                'a.userInfo',
                UserInfoEntity,
                'c',
                'c.unionid = a.openid'
            )
            .andWhere('a.createById = :userid', { userid: id })
            .orderBy("a.createTime", "DESC")
        if (BodyData.status >= 0) {
            find.andWhere("a.status = :status", { status: BodyData.status })
        }
        let data: any = await this.entityRenderPage(find, BodyData, false);
        console.log(data, 'data')
        data.code = 1000
        return data
    }

    // 获取订单详情
    async getOrderInfo(BodyData) {
        let data = await this.orderOrderEntity.createQueryBuilder('a')
            .leftJoinAndMapOne(
                "a.beNurseInfo",       // 映射到主表实体的属性名
                NursingPersonEntity,                  // 子表实体类
                'b',
                'b.id = a.beNurseId'
            )
            .leftJoinAndMapOne(
                'a.userInfo',
                UserInfoEntity,
                'c',
                'c.unionid = a.openid'
            )
            .leftJoinAndMapOne(
                'a.addressInfo',
                AddressInfoEntity,
                'd',
                'd.id = a.beNurseAddressId'
            ).leftJoinAndMapOne(
                'a.nurseInfo',
                NurseInfoEntity,
                'f',
                'f.id = a.nurseId'
            )
            .where("a.id = :id", { id: BodyData.id })
            .getOne();
        let res = {
            code: 1000,
            data,
            massage: ''
        }
        return res
    }

    // 微信回调
    async wxOrderResult(query: any) {
        // let appid = 'wxc606b8c3d53b93d1'
        // let mchid = "1692692419"
        let appid = ''
        let mchid = ""
        let keyFileName = ""
        let keyFoldersName = ""
        let certFileName = ""
        let certFoldersName = ""
        let notify_url = ""
        // 查找单个
        let key = 'd8a7u2l6i4z1f6a1t1k4n9o9n9z4g9n7' // 解密
        let orderPayItem = await this.payConfigEntity.findOneBy({ baseStatus: 1 })
        let { mchId, appId, apiclient_key, apiclient_cert, notifyUrl } = orderPayItem
        if (!mchId || !appId || !apiclient_key || !apiclient_cert || !notifyUrl) {
            throw new Error("商户信息不全，请联系管理员")
        } else {
            let apiclientKey = apiclient_key.split('/')
            let apiclientCert = apiclient_cert.split('/')
            appid = appId
            mchid = mchId
            keyFileName = apiclientKey[0]
            keyFoldersName = apiclientKey[1]
            certFileName = apiclientCert[0]
            certFoldersName = apiclientCert[1]
            notify_url = notifyUrl
        }
        const filePathkey = path.join(
            this.app.getBaseDir(),
            '..',
            'src',
            'modules',
            'order',
            'service',
            keyFileName,
            keyFoldersName
        );
        const filePathCert = path.join(
            this.app.getBaseDir(),
            '..',
            'src',
            'modules',
            'order',
            'service',
            certFileName,
            certFoldersName
        );
        const pay = new WxPay({
            appid, // '直连商户申请的公众号或移动应用appid'
            mchid,
            publicKey: fs.readFileSync(filePathCert), // 公钥
            privateKey: fs.readFileSync(filePathkey), // 秘钥
        });
        let { resource } = query
        const result = pay.decipher_gcm(resource.ciphertext, resource.associated_data, resource.nonce, key)
        let { out_trade_no, trade_state } = result
        // let data = await this.orderInfoEntity.findOneBy({ orderNumber: out_trade_no });
        console.log(trade_state == 'SUCCESS', trade_state, '222', out_trade_no, result)
        if (trade_state == 'SUCCESS') {
            this.orderOrderEntity.update({ orderNum: out_trade_no }, { status: 1 })
            return {
                return_code: trade_state
            }
        }
    }
}
